{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 线程通信条件变量"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 场景一：先生产后消费多线程模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 基本流程：\n",
    "  - 生产者线程先获取互斥锁，检查容器状态\n",
    "  - 若容器未满则生产商品并调用`cond.notify_all()`\n",
    "  - 消费者线程获取锁后检查容器状态，若为空则调用`cond.wait()`进入等待\n",
    "- 关键操作：\n",
    "  - `cond.wait()`：执行两个原子操作：1) 释放互斥锁 2) 线程进入等待状态\n",
    "  - `cond.notify_all()`：唤醒所有等待线程，但线程需重新获取锁才能继续执行\n",
    "- 状态转换：\n",
    "  - 等待→阻塞：收到通知后从等待状态变为阻塞状态\n",
    "  - 阻塞→就绪：获取锁后变为就绪状态，等待CPU调度"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 场景二：生产一个消费一个"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 控制逻辑：\n",
    "  - 生产者检查容器`size=1`时等待，消费者检查`size=0`时等待\n",
    "  - 通过`while`循环精确控制生产消费节奏\n",
    "- 调度不确定性：\n",
    "  - 锁的获取顺序完全由操作系统调度决定\n",
    "  - 可能出现生产者连续生产或消费者连续消费的情况\n",
    "- 死锁预防：\n",
    "  - 必须使用`while`循环而非`if`判断条件，防止虚假唤醒\n",
    "  - `notify_all()`比`notify_one()`更安全，减少死锁风险"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 核心机制：\n",
    "  - 互斥锁：保证对共享资源的互斥访问\n",
    "  - 条件变量：实现线程间的状态通知机制\n",
    "- 典型应用：\n",
    "  - 线程池任务队列管理\n",
    "  - 生产者-消费者问题\n",
    "  - 读写锁实现\n",
    "- 注意事项：\n",
    "  - 条件变量必须与互斥锁配合使用\n",
    "  - `wait()`调用前必须持有锁\n",
    "  - 条件判断必须使用循环结构"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 条件变量应用总结"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 状态转换详解：\n",
    "  - 等待状态：线程主动调用`wait()`进入，等待条件满足\n",
    "  - 阻塞状态：收到通知后等待获取锁的状态\n",
    "  - 就绪状态：获取锁后等待CPU调度的状态\n",
    "- 性能考量：\n",
    "  - 过多的线程唤醒可能导致\"惊群效应\"\n",
    "  - 合理设计条件判断可以减少不必要的唤醒\n",
    "- 调试建议：\n",
    "  - 使用gdb调试线程死锁问题\n",
    "  - 关注CSDN博客\"大秦坑王\"相关文章"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++17",
   "language": "C++17",
   "name": "xcpp17"
  },
  "language_info": {
   "name": "C++17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
